package com.ctw.mall.controller;


import com.ctw.mall.dao.UserMapper;
import com.ctw.mall.form.UserLoginForm;
import com.ctw.mall.form.UserRegisterForm;
import com.ctw.mall.pojo.User;
import com.ctw.mall.service.IUserService;
import com.ctw.mall.vo.ResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import static com.ctw.mall.consts.MallConst.CURRENT_USER;


@RestController
@Slf4j
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private UserMapper userMapper;

    //表单验证需要加@Valid
    @PostMapping("/user/register")
    public ResponseVo<User> register(@Valid @RequestBody(required = false) UserRegisterForm userRegisterForm
    //                           BindingResult bindingResult
    ){
//controller控制层写参数接收的入口，需要注意的是@Valid 和 BindingResult 是一 一对应的，如果有多个@Valid，那么每个@Valid后面都需要添加BindingResult用于接收bean中的校验信息
//对BindingResult的深入解析：如果在使用接口返回信息的时候，可以直接拿到bindingResult中的错误信息
//表单验证,做判断，由于字段过多，新建一个表单对象用于传参


//        if(bindingResult.hasErrors()){      //是否有错误
//            log.info("注册提交的信息有误,{} {}",
//                    bindingResult.getFieldError().getField(),   //获取字段
//                    bindingResult.getFieldError().getDefaultMessage());//此处获得的message是传入对象类中不为空后面的信息
//            return ResponseVo.error(PARAM_ERROR,bindingResult);
//        }
        User user = new User();
        BeanUtils.copyProperties(userRegisterForm,user);
       return userService.register(user);

//        log.info("username={}",userForm.getUsername());//在controller里面，通过打印日志的形式输出在控制台，不用system
//        return ResponseVo.success();
    }

    @PostMapping("/user/login")
    public ResponseVo<User> login(@Valid @RequestBody UserLoginForm userLoginForm,
//                                  BindingResult bindingResult,
                                  HttpSession session){

//        if(bindingResult.hasErrors()){      //是否有错误
//         return ResponseVo.error(PARAM_ERROR,bindingResult);
//        }
        //登陆时是把数据从数据库中取出
       ResponseVo<User> userResponseVo  = userService.login(userLoginForm.getUsername(),userLoginForm.getPassword());
        //session未设置登陆的状态,在登陆成功后才能设置
        //设置session
        //法1:
        // HttpServletRequest httpServletRequest        放在参数列表
        //HttpSession session = httpServletRequest.getSession();

        //法2:
        //从参数当中得到session
        //字符型的俗称为硬编码,最好不用
        session.setAttribute(CURRENT_USER,userResponseVo.getData());//key-value,key:String,value:object
        log.info("/login sessionId {}",session.getId());

        return userResponseVo;
    }


    //session保存在内存里,服务器重启就会丢失, 用redis存储,session是key-value形式redis也适合,光存储还不够，需要关联起来，可以用sessionId找到存储的对象，则用token+redis(分布式session) (token其实就是sessionId)
    @GetMapping("/user")
    public ResponseVo<User> userInfo(HttpSession session){
        log.info("/login sessionId {}",session.getId());
        User user = (User) session.getAttribute(CURRENT_USER);
//        if(user == null){
//            return ResponseVo.error(NEED_LOGIN);
//        }
        //当登录后用户数据做了修改，此处可以可以再查询数据库，取出数据
        User userNew=userMapper.selectByPrimaryKey(user.getId());
        userNew.setPassword("");
        return ResponseVo.success(userNew);

    }

    //TODO 判断登录状态 拦截器(统一在一处对用户登陆状态进行判断)
/**
 * 拦截器
 * Interceptor-url
 * AOP-包名
 */
    /**
     *{@link org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory}getSessionTimeoutMinutes
     *配置当中设置了两分钟自动登出,若不设置默认值为30分钟，若设置小于一分钟，不会成功，其中java中设置了最短一分钟
     */
    //判断是否是登陆的代码多次使用(上下都用到了)查订单，购物车要事先判断是否已登录
    @PostMapping("/user/logout")
    public ResponseVo logout(HttpSession session){
        log.info("/user/logout sessionId {}",session.getId());
//        User user = (User) session.getAttribute(CURRENT_USER);//取一个session相联系的信息
//        if(user == null){
//            return ResponseVo.error(NEED_LOGIN);
//        }
        session.removeAttribute(CURRENT_USER);
        return ResponseVo.success();
    }


}
